<!DOCTYPE html>
<html>

<head>
  <title>Qute Templating Engine</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/qute" />
  <meta property="og:title" content="Qute Templating Engine" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/qute">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Qute Templating Engine</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#hello-world-with-jax-rs">Hello World with JAX-RS</a></li>
<li><a href="#type-safe-templates">Type-safe templates</a>
<ul class="sectlevel2">
<li><a href="#toplevel-type-safe-templates">Toplevel type-safe templates</a></li>
</ul>
</li>
<li><a href="#template-parameter-declarations">Template Parameter Declarations</a>
<ul class="sectlevel2">
<li><a href="#template-parameter-declaration-inside-the-template-itself">Template parameter declaration inside the template itself</a></li>
</ul>
</li>
<li><a href="#template-extension-methods">Template Extension Methods</a></li>
<li><a href="#rendering-periodic-reports">Rendering Periodic Reports</a></li>
<li><a href="#reactive-and-asynchronous-apis">Reactive and Asynchronous APIs</a></li>
<li><a href="#qute-reference-guide">Qute Reference Guide</a></li>
<li><a href="#qute-configuration-reference">Qute Configuration Reference</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Qute is a templating engine designed specifically to meet the Quarkus needs.
The usage of reflection is minimized to reduce the size of native images.
The API combines both the imperative and the non-blocking reactive style of coding.
In the development mode, all files located in <code>src/main/resources/templates</code> are watched for changes and modifications are immediately visible.
Furthermore, we try to detect most of the template problems at build time.
In this guide, you will learn how to easily render templates in your application.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>This technology is considered experimental.</p>
</div>
<div class="paragraph">
<p>In <em>experimental</em> mode, early feedback is requested to mature the idea.
There is no guarantee of stability nor long term presence in the platform until the solution matures.
Feedback is welcome on our <a href="https://groups.google.com/d/forum/quarkus-dev">mailing list</a> or as issues in our <a href="https://github.com/quarkusio/quarkus/issues">GitHub issue tracker</a>.</p>
</div>
<div class="paragraph">
<p>For a full list of possible extension statuses, check our <a href="https://quarkus.io/faq/#extension-status">FAQ entry</a>.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="hello-world-with-jax-rs"><a class="anchor" href="#hello-world-with-jax-rs"></a>Hello World with JAX-RS</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you want to use Qute in your JAX-RS application, you need to add the <code>quarkus-qute-resteasy</code> extension first.
In your <code>pom.xml</code> file, add:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-resteasy-qute&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>We&#8217;ll start with a very simple template:</p>
</div>
<div class="listingblock">
<div class="title">hello.txt</div>
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">Hello {name}! <i class="conum" data-value="1"></i><b>(1)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td><code>{name}</code> is a value expression that is evaluated when the template is rendered.</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
By default, all files located in the <code>src/main/resources/templates</code> directory and its subdirectories are registered as templates. Templates are validated during startup and watched for changes in the development mode.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Now let&#8217;s inject the "compiled" template in the resource class.</p>
</div>
<div class="listingblock">
<div class="title">HelloResource.java</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.quarkus.sample;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;

import io.quarkus.qute.TemplateInstance;
import io.quarkus.qute.Template;

@Path("hello")
public class HelloResource {

    @Inject
    Template hello; <i class="conum" data-value="1"></i><b>(1)</b>

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public TemplateInstance get(@QueryParam("name") String name) {
        return hello.data("name", name); <i class="conum" data-value="2"></i><b>(2)</b> <i class="conum" data-value="3"></i><b>(3)</b>
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>If there is no <code>@ResourcePath</code> qualifier provided, the field name is used to locate the template. In this particular case, we&#8217;re injecting a template with path <code>templates/hello.txt</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td><code>Template.data()</code> returns a new template instance that can be customized before the actual rendering is triggered. In this case, we put the name value under the key <code>name</code>. The data map is accessible during rendering.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>Note that we don&#8217;t trigger the rendering - this is done automatically by a special <code>ContainerResponseFilter</code> implementation.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If your application is running, you can request the endpoint:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">$ curl -w "\n" http://localhost:8080/hello?name=Martin
Hello Martin!</code></pre>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="type-safe-templates"><a class="anchor" href="#type-safe-templates"></a>Type-safe templates</h2>
<div class="sectionbody">
<div class="paragraph">
<p>There&#8217;s an alternate way to declare your templates in your Java code, which relies on the following convention:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Organise your template files in the <code>/src/main/resources/templates</code> directory, by grouping them into one directory per resource class. So, if
your <code>ItemResource</code> class references two templates <code>hello</code> and <code>goodbye</code>, place them at <code>/src/main/resources/templates/ItemResource/hello.txt</code>
and <code>/src/main/resources/templates/ItemResource/goodbye.txt</code>. Grouping templates per resource class makes it easier to navigate to them.</p>
</li>
<li>
<p>In each of your resource class, declare a <code>@CheckedTemplate static class Template {}</code> class within your resource class.</p>
</li>
<li>
<p>Declare one <code>public static native TemplateInstance method();</code> per template file for your resource.</p>
</li>
<li>
<p>Use those static methods to build your template instances.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Here&#8217;s the previous example, rewritten using this style:</p>
</div>
<div class="paragraph">
<p>We&#8217;ll start with a very simple template:</p>
</div>
<div class="listingblock">
<div class="title">HelloResource/hello.txt</div>
<div class="content">
<pre class="highlightjs highlight"><code class="language-none hljs">Hello {name}! <i class="conum" data-value="1"></i><b>(1)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td><code>{name}</code> is a value expression that is evaluated when the template is rendered.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Now let&#8217;s declare and use those templates in the resource class.</p>
</div>
<div class="listingblock">
<div class="title">HelloResource.java</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.quarkus.sample;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;

import io.quarkus.qute.TemplateInstance;
import io.quarkus.qute.api.CheckedTemplate;

@Path("hello")
public class HelloResource {

    @CheckedTemplate
    public static class Templates {
        public static native TemplateInstance hello(); <i class="conum" data-value="1"></i><b>(1)</b>
    }

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public TemplateInstance get(@QueryParam("name") String name) {
        return Templates.hello().data("name", name); <i class="conum" data-value="2"></i><b>(2)</b> <i class="conum" data-value="3"></i><b>(3)</b>
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>This declares a template with path <code>templates/HelloResource/hello.txt</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td><code>Templates.hello()</code> returns a new template instance that can be customized before the actual rendering is triggered. In this case, we put the name value under the key <code>name</code>. The data map is accessible during rendering.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>Note that we don&#8217;t trigger the rendering - this is done automatically by a special <code>ContainerResponseFilter</code> implementation.</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Once you have declared a <code>@CheckedTemplate</code> class, we will check that all its methods point to existing templates, so if you try to use a template
from your Java code and you forgot to add it, we will let you know at build time :)
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Keep in mind this style of declaration allows you to reference templates declared in other resources too:</p>
</div>
<div class="listingblock">
<div class="title">HelloResource.java</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.quarkus.sample;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;

import io.quarkus.qute.TemplateInstance;

@Path("goodbye")
public class GoodbyeResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public TemplateInstance get(@QueryParam("name") String name) {
        return HelloResource.Templates.hello().data("name", name);
    }
}</code></pre>
</div>
</div>
<div class="sect2">
<h3 id="toplevel-type-safe-templates"><a class="anchor" href="#toplevel-type-safe-templates"></a>Toplevel type-safe templates</h3>
<div class="paragraph">
<p>Naturally, if you want to declare templates at the toplevel, directly in <code>/src/main/resources/templates/hello.txt</code>, for example,
you can declare them in a toplevel (non-nested) <code>Templates</code> class:</p>
</div>
<div class="listingblock">
<div class="title">HelloResource.java</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.quarkus.sample;

import io.quarkus.qute.TemplateInstance;
import io.quarkus.qute.Template;
import io.quarkus.qute.api.CheckedTemplate;

@CheckedTemplate
public class Templates {
    public static native TemplateInstance hello(); <i class="conum" data-value="1"></i><b>(1)</b>
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>This declares a template with path <code>templates/hello.txt</code>.</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="template-parameter-declarations"><a class="anchor" href="#template-parameter-declarations"></a>Template Parameter Declarations</h2>
<div class="sectionbody">
<div class="paragraph">
<p>If you declare a <strong>parameter declaration</strong> in a template then Qute attempts to validate all expressions that reference this parameter and if an incorrect expression is found the build fails.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s suppose we have a simple class like this:</p>
</div>
<div class="listingblock">
<div class="title">Item.java</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public class Item {
    public String name;
    public BigDecimal price;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>And we&#8217;d like to render a simple HTML page that contains the item name and price.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s start again with the template:</p>
</div>
<div class="listingblock">
<div class="title">ItemResource/item.html</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="html" class="language-html hljs">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset="UTF-8"&gt;
&lt;title&gt;{item.name}&lt;/title&gt; <i class="conum" data-value="1"></i><b>(1)</b>
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;{item.name}&lt;/h1&gt;
    &lt;div&gt;Price: {item.price}&lt;/div&gt; <i class="conum" data-value="2"></i><b>(2)</b>
&lt;/body&gt;
&lt;/html&gt;</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>This expression is validated. Try to change the expression to <code>{item.nonSense}</code> and the build should fail.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>This is also validated.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Finally, let&#8217;s create a resource class with type-safe templates:</p>
</div>
<div class="listingblock">
<div class="title">ItemResource.java</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.quarkus.sample;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import io.quarkus.qute.TemplateInstance;
import io.quarkus.qute.Template;
import io.quarkus.qute.api.CheckedTemplate;

@Path("item")
public class ItemResource {

    @CheckedTemplate
    public static class Templates {
        public static native TemplateInstance item(Item item); <i class="conum" data-value="1"></i><b>(1)</b>
    }

    @GET
    @Path("{id}")
    @Produces(MediaType.TEXT_HTML)
    public TemplateInstance get(@PathParam("id") Integer id) {
        return Templates.item(service.findItem(id)); <i class="conum" data-value="2"></i><b>(2)</b>
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Declare a method that gives us a <code>TemplateInstance</code> for <code>templates/ItemResource/item.html</code> and declare its <code>Item item</code> parameter so we can validate the template.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Make the <code>Item</code> object accessible in the template.</td>
</tr>
</table>
</div>
<div class="sect2">
<h3 id="template-parameter-declaration-inside-the-template-itself"><a class="anchor" href="#template-parameter-declaration-inside-the-template-itself"></a>Template parameter declaration inside the template itself</h3>
<div class="paragraph">
<p>Alternatively, you can declare your template parameters in the template file itself.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s start again with the template:</p>
</div>
<div class="listingblock">
<div class="title">item.html</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="html" class="language-html hljs">{@org.acme.Item item} <i class="conum" data-value="1"></i><b>(1)</b>
&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset="UTF-8"&gt;
&lt;title&gt;{item.name}&lt;/title&gt; <i class="conum" data-value="2"></i><b>(2)</b>
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;{item.name}&lt;/h1&gt;
    &lt;div&gt;Price: {item.price}&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Optional parameter declaration. Qute attempts to validate all expressions that reference the parameter <code>item</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>This expression is validated. Try to change the expression to <code>{item.nonSense}</code> and the build should fail.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Finally, let&#8217;s create a resource class.</p>
</div>
<div class="listingblock">
<div class="title">ItemResource.java</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.quarkus.sample;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import io.quarkus.qute.TemplateInstance;
import io.quarkus.qute.Template;

@Path("item")
public class ItemResource {

    @Inject
    ItemService service;

    @Inject
    Template item; <i class="conum" data-value="1"></i><b>(1)</b>

    @GET
    @Path("{id}")
    @Produces(MediaType.TEXT_HTML)
    public TemplateInstance get(@PathParam("id") Integer id) {
        return item.data("item", service.findItem(id)); <i class="conum" data-value="2"></i><b>(2)</b>
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Inject the template with path <code>templates/item.html</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Make the <code>Item</code> object accessible in the template.</td>
</tr>
</table>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="template-extension-methods"><a class="anchor" href="#template-extension-methods"></a>Template Extension Methods</h2>
<div class="sectionbody">
<div class="paragraph">
<p><strong>Template extension methods</strong> are used to extend the set of accessible properties of data objects.</p>
</div>
<div class="paragraph">
<p>Sometimes, you&#8217;re not in control of the classes that you want to use in your template, and you cannot add methods
to them. Template extension methods allows you to declare new method for those classes that will be available
from your templates just as if they belonged to the target class.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s keep extending on our simple HTML page that contains the item name, price and add a discounted price.
The discounted price is sometimes called a "computed property".
We will implement a template extension method to render this property easily.
Let&#8217;s update our template:</p>
</div>
<div class="listingblock">
<div class="title">HelloResource/item.html</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="html" class="language-html hljs">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset="UTF-8"&gt;
&lt;title&gt;{item.name}&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;{item.name}&lt;/h1&gt;
    &lt;div&gt;Price: {item.price}&lt;/div&gt;
    {#if item.price &gt; 100} <i class="conum" data-value="1"></i><b>(1)</b>
    &lt;div&gt;Discounted Price: {item.discountedPrice}&lt;/div&gt; <i class="conum" data-value="2"></i><b>(2)</b>
    {/if}
&lt;/body&gt;
&lt;/html&gt;</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td><code>if</code> is a basic control flow section.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>This expression is also validated against the <code>Item</code> class and obviously there is no such property declared. However, there is a template extension method declared on the <code>TemplateExtensions</code> class - see below.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Finally, let&#8217;s create a class where we put all our extension methods:</p>
</div>
<div class="listingblock">
<div class="title">TemplateExtensions.java</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.quarkus.sample;

import io.quarkus.qute.TemplateExtension;

@TemplateExtension
public class TemplateExtensions {

    public static BigDecimal discountedPrice(Item item) { <i class="conum" data-value="1"></i><b>(1)</b>
        return item.price.multiply(new BigDecimal("0.9"));
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>A static template extension method can be used to add "computed properties" to a data class. The class of the first parameter is used to match the base object and the method name is used to match the property name.</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
you can place template extension methods in every class if you annotate them with <code>@TemplateExtension</code> but we advise to keep them either
grouped by target type, or in a single <code>TemplateExtensions</code> class by convention.
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="rendering-periodic-reports"><a class="anchor" href="#rendering-periodic-reports"></a>Rendering Periodic Reports</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Templating engine could be also very useful when rendering periodic reports.
You&#8217;ll need to add the <code>quarkus-scheduler</code> and <code>quarkus-qute</code> extensions first.
In your <code>pom.xml</code> file, add:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-qute&lt;/artifactId&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-scheduler&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Let&#8217;s suppose the have a <code>SampleService</code> bean whose <code>get()</code> method returns a list of samples.</p>
</div>
<div class="listingblock">
<div class="title">Sample.java</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public class Sample {
    public boolean valid;
    public String name;
    public String data;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The template is simple:</p>
</div>
<div class="listingblock">
<div class="title">report.html</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="html" class="language-html hljs">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;meta charset="UTF-8"&gt;
&lt;title&gt;Report {now}&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;h1&gt;Report {now}&lt;/h1&gt;
    {#for sample in samples} <i class="conum" data-value="1"></i><b>(1)</b>
      &lt;h2&gt;{sample.name ?: 'Unknown'}&lt;/h2&gt; <i class="conum" data-value="2"></i><b>(2)</b>
      &lt;p&gt;
      {#if sample.valid}
        {sample.data}
      {#else}
        &lt;strong&gt;Invalid sample found&lt;/strong&gt;.
      {/if}
      &lt;/p&gt;
    {/for}
&lt;/body&gt;
&lt;/html&gt;</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>The loop section makes it possible to iterate over iterables, maps and streams.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>This value expression is using the <a href="https://en.wikipedia.org/wiki/Elvis_operator">elvis operator</a> - if the name is null the default value is used.</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="title">ReportGenerator.java</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package org.acme.quarkus.sample;

import javax.inject.Inject;

import io.quarkus.qute.Template;
import io.quarkus.qute.api.ResourcePath;
import io.quarkus.scheduler.Scheduled;

public class ReportGenerator {

    @Inject
    SampleService service;

    @ResourcePath("reports/v1/report_01") <i class="conum" data-value="1"></i><b>(1)</b>
    Template report;

    @Scheduled(cron="0 30 * * * ?") <i class="conum" data-value="2"></i><b>(2)</b>
    void generate() {
        String result = report
            .data("samples", service.get())
            .data("now", java.time.LocalDateTime.now())
            .render(); <i class="conum" data-value="3"></i><b>(3)</b>
        // Write the result somewhere...
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>In this case, we use the <code>@ResourcePath</code> qualifier to specify the template path: <code>templates/reports/v1/report_01.html</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Use the <code>@Scheduled</code> annotation to instruct Quarkus to execute this method on the half hour. For more information see the <a href="scheduler">Scheduler</a> guide.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>The <code>TemplateInstance.render()</code> method triggers rendering. Note that this method blocks the current thread.</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect1">
<h2 id="reactive-and-asynchronous-apis"><a class="anchor" href="#reactive-and-asynchronous-apis"></a>Reactive and Asynchronous APIs</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Templates can be rendered as a <code>CompletionStage&lt;String&gt;</code> (completed with the rendered output asynchronously) or as <code>Publisher&lt;String&gt;</code> containing the rendered chunks:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">CompletionStage&lt;String&gt; async = template.data("name", "neo").renderAsync();
Publisher&lt;String&gt; publisher = template.data("name", "neo").publisher();</code></pre>
</div>
</div>
<div class="paragraph">
<p>In the case of a <code>Publisher</code>, the template is rendered chunk by chunk following the requests from the subscriber.
The rendering is not started until a subscriber requests it.
The returned <code>Publisher</code> is an instance of <code>io.smallrye.mutiny.Multi</code>.</p>
</div>
<div class="paragraph">
<p>It is possible to create an instance of <code>io.smallrye.mutiny.Uni</code> as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">Uni&lt;String&gt; uni = Uni.createFrom().completionStage(() -&gt; template.data("name", "neo").renderAsync());</code></pre>
</div>
</div>
<div class="paragraph">
<p>In this case, the rendering only starts once the subscriber requests it.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="qute-reference-guide"><a class="anchor" href="#qute-reference-guide"></a>Qute Reference Guide</h2>
<div class="sectionbody">
<div class="paragraph">
<p>To learn more about Qute, please refer to the <a href="qute-reference">Qute reference guide</a>.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="qute-configuration-reference"><a class="anchor" href="#qute-configuration-reference"></a>Qute Configuration Reference</h2>
<div class="sectionbody">
<div class="paragraph configuration-legend">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> Configuration property fixed at build time - All other configuration properties are overridable at runtime</p>
</div>
<table class="tableblock frame-all grid-all stretch configuration-reference searchable">
<colgroup>
<col style="width: 80%;">
<col style="width: 10%;">
<col style="width: 10%;">
</colgroup>
<tbody>
<tr>
<th class="tableblock halign-left valign-top"><p class="tableblock"><a id="quarkus-qute_configuration"></a><a href="#quarkus-qute_configuration">Configuration property</a></p></th>
<th class="tableblock halign-left valign-middle"><p class="tableblock">Type</p></th>
<th class="tableblock halign-left valign-middle"><p class="tableblock">Default</p></th>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-qute_quarkus.qute.suffixes"></a><code><a href="#quarkus-qute_quarkus.qute.suffixes">quarkus.qute.suffixes</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>The set of suffixes used when attempting to locate a template file.</p>
</div>
<div class="paragraph">
<p>By default, <code>engine.getTemplate("foo")</code> would result in several lookups: <code>foo</code>, <code>foo.html</code>, <code>foo.txt</code>, etc.</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">list of string</p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>qute.html,qute.txt,html,txt</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-qute_quarkus.qute.remove-standalone-lines"></a><code><a href="#quarkus-qute_quarkus.qute.remove-standalone-lines">quarkus.qute.remove-standalone-lines</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>Specify whether the parser should remove standalone lines from the output. A standalone line is a line that contains only section tags, parameter declarations and whitespace characters.</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">boolean</p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>true</code></p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p><span class="icon"><i class="fa fa-lock" title="Fixed at build time"></i></span> <a id="quarkus-qute_quarkus.qute.content-types-content-types"></a><code><a href="#quarkus-qute_quarkus.qute.content-types-content-types">quarkus.qute.content-types</a></code></p>
</div>
<div class="openblock description">
<div class="content">
<div class="paragraph">
<p>The additional map of suffixes to content types. This map is used when working with template variants. By default, the <code>java.net.URLConnection#getFileNameMap()</code> is used to determine the content type of a template file.</p>
</div>
</div>
</div></div></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock"><code>Map&lt;String,String&gt;</code></p></td>
<td class="tableblock halign-left valign-middle"><p class="tableblock">required <span class="icon"><i class="fa fa-exclamation-circle" title="Configuration property is required"></i></span></p></td>
</tr>
</tbody>
</table>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
